#include "mat4.h"

mat4::mat4()
{
	m[0] = m[5] = m[10] = m[15] = 1;
	m[1] = m[2] = m[3] = m[4] =
	m[6] = m[7] = m[8] = m[9] =
	m[11] = m[12] = m[13] = 0;
}

mat4::mat4(float value)
{
	for(int i=0;i<16;++i)
		m[i] = value;
}

mat4::mat4(const mat4 &copy)
{
	for(int i=0;i<16;++i)
		m[i] = copy.m[i];
}


mat4 mat4::operator * (float value)
{
	mat4 mat;
	for(int i=0;i<16;++i)
		mat.m[i] = m[i]*value;

	return mat;
}

vec4 mat4::operator * (const vec4 &v)
{
	vec4 result;

	result.x = v.x * m[0 + 0*4] + v.y * m[0 + 1*4] + v.z * m[0 + 2*4] + v.w * m[0 + 3*4];
	result.y = v.x * m[1 + 0*4] + v.y * m[1 + 1*4] + v.z * m[1 + 2*4] + v.w * m[1 + 3*4];
	result.z = v.x * m[2 + 0*4] + v.y * m[2 + 1*4] + v.z * m[2 + 2*4] + v.w * m[2 + 3*4];
	result.w = v.x * m[3 + 0*4] + v.y * m[3 + 1*4] + v.z * m[3 + 2*4] + v.w * m[3 + 3*4];

	return result;
}

vec3 mat4::operator * (const vec3 &v)
{
	vec3 result;

	result.x = v.x * m[0 + 0*4] + v.y * m[0 + 1*4] + v.z * m[0 + 2*4] + m[0 + 3*4];
	result.y = v.x * m[1 + 0*4] + v.y * m[1 + 1*4] + v.z * m[1 + 2*4] + m[1 + 3*4];
	result.z = v.x * m[2 + 0*4] + v.y * m[2 + 1*4] + v.z * m[2 + 2*4] + m[2 + 3*4];

	return result;
}

mat4 mat4::operator * (const mat4 & mat)
{
	mat4 nm;

	return nm;
}

mat4& mat4::operator =  ( const mat4& mat)
{
	for(int i =0; i<16;++i)
		m[i] = mat.m[i];

	return *this;
}

mat4& mat4::operator =  ( float value)
{
	for(int i =0; i<16;++i)
		m[i] = value;

	return *this;
}

mat4& mat4::operator += ( const mat4& mat)
{
	for(int i =0; i<16;++i)
		m[i] += mat.m[i];

	return *this;
}

mat4& mat4::operator -= ( const mat4& mat)
{
	for(int i =0; i<16;++i)
		m[i]-= mat.m[i];

	return *this;
}

mat4& mat4::operator *= ( const mat4& mat)
{
	for(int i =0; i<16;++i)
		m[i] *= mat.m[i];

	return *this;
}

mat4& mat4::operator *= ( float value)
{
	for(int i =0; i<16;++i)
		m[i] *= value;

	return *this;
}

mat4& mat4::operator /= ( float value)
{
	for(int i =0; i<16;++i)
		m[i] /= value;

	return *this;
}

void mat4::MulVec4(vec4 *v)
{
	vec4 result;

	result.x = v->x * m[0 + 0*4] + v->y * m[0 + 1*4] + v->z * m[0 + 2*4] + v->w * m[0 + 3*4];
	result.y = v->x * m[1 + 0*4] + v->y * m[1 + 1*4] + v->z * m[1 + 2*4] + v->w * m[1 + 3*4];
	result.z = v->x * m[2 + 0*4] + v->y * m[2 + 1*4] + v->z * m[2 + 2*4] + v->w * m[2 + 3*4];
	result.w = v->x * m[3 + 0*4] + v->y * m[3 + 1*4] + v->z * m[3 + 2*4] + v->w * m[3 + 3*4];

	v->x = result.x;
	v->y = result.y;
	v->z = result.z;
	v->w = result.w;
}

void mat4::MulMat4(mat4 *v)
{
	mat4 result;

	for(int i =0;i<4;++i)
	{
		for(int j=0;j<4;++j)
		{
			
		}
	}
}

void mat4::GetMatrix(float *f)
{
}

void mat4::GetTransponseMatrix(float *f)
{
}

void mat4::Transponse()
{
}

void mat4::identity()
{
	m[0] = m[5] = m[10] = m[15] = 1;
	m[1] = m[2] = m[3] = m[4] =
	m[6] = m[7] = m[8] = m[9] =
	m[11] = m[12] = m[13] = 0;
}

void mat4::rotate(float pitch,float yaw, float roll)
{
}

void mat4::scale(float sx, float sy, float sz)
{
}

void mat4::scale(float value)
{
}

void mat4::rotate(quat &rot)
{
}

void mat4::rotate(mat3 &rot)
{
}

void mat4::translate(float x,float y,float z)
{
	m[12] = x;
	m[13] = y;
	m[14] = z;
}

void mat4::translate(vec3 &tr)
{
	m[12] = tr.x;
	m[13] = tr.y;
	m[14] = tr.z;
}



float mat4::Get(int i,int j)
{
	return m[A(i,j)];
}

void mat4::Set(int i,int j, float val)
{
	m[A(i,j)] = val;
}


vec4 operator * (const mat4 &mat, const vec4 &v)
{
	vec4 result;

	result.x = v.x * mat.m[0 + 0*4] + v.y * mat.m[0 + 1*4] + v.z * mat.m[0 + 2*4] + v.w * mat.m[0 + 3*4];
	result.y = v.x * mat.m[1 + 0*4] + v.y * mat.m[1 + 1*4] + v.z * mat.m[1 + 2*4] + v.w * mat.m[1 + 3*4];
	result.z = v.x * mat.m[2 + 0*4] + v.y * mat.m[2 + 1*4] + v.z * mat.m[2 + 2*4] + v.w * mat.m[2 + 3*4];
	result.w = v.x * mat.m[3 + 0*4] + v.y * mat.m[3 + 1*4] + v.z * mat.m[3 + 2*4] + v.w * mat.m[3 + 3*4];

	return result;
}

vec3 operator * (const mat4 &mat, const vec3 &v)
{
	vec3 result;

	result.x = v.x * mat.m[0 + 0*4] + v.y * mat.m[0 + 1*4] + v.z * mat.m[0 + 2*4] + mat.m[0 + 3*4];
	result.y = v.x * mat.m[1 + 0*4] + v.y * mat.m[1 + 1*4] + v.z * mat.m[1 + 2*4] + mat.m[1 + 3*4];
	result.z = v.x * mat.m[2 + 0*4] + v.y * mat.m[2 + 1*4] + v.z * mat.m[2 + 2*4] + mat.m[2 + 3*4];

	return result;
}
